//
//  AppDelegate.m
//  EncrypDecrypTool
//
//  Created by apple on 2019/12/3.
//  Copyright © 2019 apple. All rights reserved.
//

#import "AppDelegate.h"
#include <CommonCrypto/CommonDigest.h>

@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;

@property (weak) IBOutlet NSTextField *dirPathTField;   // 文件夹路径
@property (weak) IBOutlet NSTextField *filePrefixTField;// 指定文件前缀
@property (weak) IBOutlet NSTextField *fileSuffixTField;// 指定文件后缀
@property (weak) IBOutlet NSTextField *secretKeyTField; // 文件加密秘钥

@property (weak) IBOutlet NSTextField *prompt; // 提示信息
@property (weak) IBOutlet NSButton *openExportResPath;  // 导出资源路径信息按钮
@property (weak) IBOutlet NSScrollView *xorDecryptTools;// XOR工具代码,预览视图

@property(nonatomic, copy) NSString *encryptExportedPath;// 加密资源导出路径
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    NSLog(@"--> applicationDidFinishLaunching()");
}


- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
    NSLog(@"--> applicationWillTerminate()");
}

- (IBAction)browse:(id)sender {
    __weak __typeof(self) weak = self;
    NSOpenPanel* panel = [NSOpenPanel openPanel];
    [panel setCanCreateDirectories:YES];  //是否可以创建文件夹
    [panel setCanChooseDirectories:YES];  //是否能打开文件夹
    [panel beginWithCompletionHandler:^(NSInteger result) {
        if (result == NSModalResponseOK) {
            NSMutableArray* filePaths = [[NSMutableArray alloc] init];
            for (NSURL* elemnet in [panel URLs]) {
                [filePaths addObject:[elemnet path]];
            }
            
            NSLog(@"filePaths : %@",filePaths);
            weak.dirPathTField.stringValue = filePaths[0];
        }
    }];
}

- (IBAction)starte:(id)sender {
    if (self.dirPathTField.stringValue.length == 0) {
        self.prompt.stringValue = @"请先指定需加密处理的文件夹路径！";
        return;
    }
    
    if (self.secretKeyTField.stringValue.length == 0) {
        self.prompt.stringValue = @"加密秘钥不能为空！";
        return;
    }
    
    NSLog(@"指定文件的前缀名：%@",self.filePrefixTField.stringValue);
    NSLog(@"指定文件的后缀名：%@",self.fileSuffixTField.stringValue);
    NSLog(@"用于文件加密秘钥：%@",[self md5:self.secretKeyTField.stringValue]);
    
    [self resourceEncrypt];
}

- (IBAction)openExport:(id)sender {
    if (self.encryptExportedPath.length == 0) {
        return;
    }
    
    /// 启动外部进程,执行命令：open 文件夹路径
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:@"/usr/bin/open"];//可执行文件路径，即终端命令 open
    [task setArguments:@[self.encryptExportedPath]];//参数，即文件夹路径
    [task launch];//启动task
    [task waitUntilExit];//直到程序运行结束，相应程序才会往下执行
}

- (IBAction)getXOR_Tools:(id)sender {
    NSTextView *txView = [[NSTextView alloc]init];
    [txView setAutoresizingMask:NSViewHeightSizable];
    txView.frame = NSMakeRect(0, 0,self.xorDecryptTools.bounds.size.width, self.xorDecryptTools.bounds.size.height);
    [txView setMinSize:self.xorDecryptTools.bounds.size];
    [txView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
    
    [txView setAutoresizingMask:NSViewWidthSizable];
    
    [[txView textContainer] setContainerSize:NSMakeSize(self.xorDecryptTools.bounds.size.width - 40, FLT_MAX)];
    [[txView textContainer] setWidthTracksTextView:YES];
    
    [txView setVerticallyResizable:YES];
    [txView setHorizontallyResizable:YES];
    txView.string = [self xor_tools];
    [self.xorDecryptTools setDocumentView:txView];
}

#pragma mark - Tools
/// 遍历资源文件进行加密
- (void)resourceEncrypt {
    // 获取文件夹下的所以文件放入数组中
    NSArray *shortPicNameArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.dirPathTField.stringValue error:nil];
    NSLog(@"shortPicNameArray = %@",shortPicNameArray);
    
    for (NSString *shortPicName in shortPicNameArray) {
        // 截取原文件,名称处理
        NSRange range = [shortPicName rangeOfString:@"."];
        //NSLog(@"range.location = %ld,   range.length = %ld",range.location,range.length);
        
        // 原文件名
        NSString *tempShortPicName = [shortPicName substringToIndex:range.location];
        //NSLog(@"tempShortPicName = %@",tempShortPicName);
        
        // 原文件后缀名
        NSString *tempShortPicSufName = [shortPicName substringFromIndex:range.location];
        //NSLog(@"tempShortPicSufName = %@",tempShortPicSufName);
        // 跳过 .DS_Store 文件的加密
        if ([tempShortPicSufName isEqualToString:@".DS_Store"]) {
            continue;
        }
        
        // 读取文件路径
        NSString *fullPicPath = [self.dirPathTField.stringValue stringByAppendingPathComponent:shortPicName];
        //NSLog(@"fullPicPath = %@",fullPicPath);
        
        // 读取原始数据
        NSData *fullPicData = [NSData dataWithContentsOfFile:fullPicPath];
        //NSLog(@"fullPicData = %@",fullPicData);
        
        // 对数据进行XOR加密
        NSData *encodeFullPicData = [self xorEncryptWithSourceData:fullPicData secretKey:[self md5:self.secretKeyTField.stringValue]];
        
        // 判断是否制定特定后缀名，若未指定，则用原文件后缀名
        NSString *newShortPicName;
        if (self.fileSuffixTField.stringValue.length > 0) {
            newShortPicName = [NSString stringWithFormat:@"%@%@%@",self.filePrefixTField.stringValue,tempShortPicName,self.fileSuffixTField.stringValue];
        }else{
            newShortPicName = [NSString stringWithFormat:@"%@%@%@",self.filePrefixTField.stringValue,tempShortPicName,tempShortPicSufName];
        }
        
        // 在当前文件夹下创建一个EncryptRes子文件夹来存储加密后的资源文件
//        NSString *newDirPath = [self.dirPathTField.stringValue stringByAppendingFormat:@"/EncryptRes"];
//        NSFileManager *fm = [NSFileManager defaultManager];
//        //判断文件是否存在，不存在才创建
//        BOOL result = [fm fileExistsAtPath:newDirPath];
//        if (!result) {
//            [fm createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:nil];
//        }
        
        // 在桌面创建一个文件夹来存储加密后的资源文件
        NSFileManager *fm = [NSFileManager defaultManager];
        NSArray *paths = [fm URLsForDirectory:NSDesktopDirectory inDomains:NSUserDomainMask];
        NSURL *path = [paths objectAtIndex:0];
        NSString *myFiledFolder = [path.relativePath stringByAppendingFormat:@"/EncryptRes %@",[self getCurrentTimes]];
        //NSLog(@"myFiledFolder = %@",myFiledFolder);
        //判断文件是否存在，不存在才创建
        BOOL result = [fm fileExistsAtPath:myFiledFolder];
        if (!result) {
            [fm createDirectoryAtPath:myFiledFolder withIntermediateDirectories:YES attributes:nil error:nil];
        }
        // 变量存储，加密资源导出路径
        self.encryptExportedPath = myFiledFolder;
        // 拼接文件路径
        NSString *newFullPicPath = [myFiledFolder stringByAppendingPathComponent:newShortPicName];
        //NSLog(@"newfullPicPath: %@",newFullPicPath);
        
        // 写入加密后的数据
        [encodeFullPicData writeToFile:newFullPicPath atomically:YES];
    }
    
    self.prompt.stringValue = @"加密文件处理完成！";
    [self.openExportResPath setTitle:[NSString stringWithFormat:@"点击打开：%@",self.encryptExportedPath]];
}

/// 按照指定格式输出当前日期
-(NSString*)getCurrentTimes{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    // 设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    [formatter setDateFormat:@"YYYY-MM-dd HH-mm-ss"];
    //现在时间,你可以输出来看下是什么格式
    NSDate *datenow = [NSDate date];
    // 将nsdate按formatter格式转成nsstring
    NSString *currentTimeString = [formatter stringFromDate:datenow];
    //NSLog(@"currentTimeString =  %@",currentTimeString);
    return currentTimeString;
}

/**
 MD5加密【备注：需导入 #include <CommonCrypto/CommonDigest.h> 】

 @param text 需要加密原串
 @return  MD5后值转小写串
 */
- (NSString *)md5:(NSString *)text {
    const char *cStr = [text UTF8String];
    unsigned char result[16];
    
    CC_MD5(cStr, (unsigned char)strlen(cStr), result );
    NSString *md5Str = [NSString stringWithFormat:
                        @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                        result[0], result[1], result[2], result[3],
                        result[4], result[5], result[6], result[7],
                        result[8], result[9], result[10], result[11],
                        result[12], result[13], result[14], result[15]
                        ];
    return [md5Str lowercaseString];
}

/**
 异或加解密（XOR）--文本、图片、音视频
 
 @param sourceData 资源Data数据
 @param secretKey  加密秘钥
 @return 加密Data数据
 */
- (NSData *)xorEncryptWithSourceData:(NSData *)sourceData secretKey:(NSString *)secretKey {
    // 获取key的长度
    NSInteger length = secretKey.length;
    // 将OC字符串转换为C字符串
    const char *keys = [secretKey cStringUsingEncoding:NSASCIIStringEncoding];
    unsigned char cKey[length];
    //memcpy函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中
    memcpy(cKey, keys, length);
    // 数据初始化，空间未分配 配合使用 appendBytes
    NSMutableData *encryptData = [[NSMutableData alloc] initWithCapacity:length];
    // 获取字节指针
    const Byte *point = sourceData.bytes;
    for (int i = 0; i < sourceData.length; i++) {
        // 算出当前位置字节，要和密钥的异或运算的密钥字节
        int l = i % length;
        char c = cKey[l];
        // 异或运算
        Byte b = (Byte) ((point[i]) ^ c);
        // 追加字节
        [encryptData appendBytes:&b length:1];
    }
    return encryptData.copy;
}
/// 读取工具代码
- (NSString *)xor_tools {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"decrypt" ofType:@"txt"];
    NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    
    return content;
}

@end
